import { getCurrentInstance, nextTick, provide, inject, ComponentInternalInstance } from "vue";
import { I18nInjectionKey } from "vue-i18n";
import dataSourceMap from "./dataSourceMap";
import { useRouter, useRoute } from "vue-router";
import * as utils from "@/utils"
const AppSymbol = Symbol("AppSymbol")
export const lowcodeWrap = (props: any, context: any) => {

  const global: any = { };
  const instance = getCurrentInstance() as ComponentInternalInstance;
  const appContext = instance.appContext
  const { t, locale }: any = inject(I18nInjectionKey)?.global;
  const emit = context.emit;
  const router = useRouter();
  const route = useRoute();
  const ref = (ref: any) => instance?.refs[ref],
    setState = async (newState: any, callback: any) => {
      Object.assign(global.state, newState);
      await nextTick(() => callback?.apply(global));
    },
    getLocale = () => locale.value,
    setLocale = (val: any) => {
      locale.value = val;
    },
    location = () => window.location,
    history = () => window.history;


  Object.defineProperties(global, {
    props: { get: () => props },
    emit: { get: () => emit },
    setState: { get: () => setState },
    appStore: { get: () => inject(AppSymbol) },
    i18n: { get: () => t },
    getLocale: { get: () => getLocale },
    setLocale: { get: () => setLocale },
    reload: { get: async () => {
        await router.push({
          name: 'reload',
        })
      }
    },
    location: { get: location },
    history: { get: history },
    utils: { get: ()=> utils },
    dataSourceMap: { get: () => dataSourceMap },
    router: { get: () => router },
    route: { get: () => route },
    config: { get: () => appContext.config.globalProperties },
    $: { get: () => ref }
  });

  const wrap = (fn: any) => {
    if (typeof fn === "function") {
      return (...args: any) => fn.apply(global, args);
    }

    Object.entries(fn).forEach(([name, value]) => {
      Object.defineProperty(global, name, {
        get: () => value,
      });
    });

    fn.t = t;

    return fn;
  };

  return wrap;
};

export default () => {
  const i18n: any = inject(I18nInjectionKey);

  provide(I18nInjectionKey, i18n);

  const stores = {
    app: inject(AppSymbol),
  };

  return { t: i18n.global.t, stores, lowcodeWrap };
};
